<?php

declare(strict_types=1);

namespace app\sys\controller;

use think\admin\model\SysMerchant;
use think\admin\model\SysRelation;
use think\admin\model\SysTenant;
use think\admin\Controller;
use think\admin\extend\CodeExtend;
use think\exception\HttpResponseException;


/**
 * 租户接口
 * Class Tenant
 * @package app\biz\controller
 */
class Tenant extends Controller
{
    /**
     * 租户分页列表
     * @auth true
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function page()
    {
        $query = SysTenant::mQuery();
        $query->where(['is_deleted' => 0]);

        // 数据列表搜索过滤
        $query->equal('tenant_id,tenant_code,status')->dateBetween('created_at');
        $query->like('tenant_name,auth_status');
        $query->dataScope('created_by');
        $lists = $query->order('id ASC')->page();
    }

    /**
     * 列表数据处理
     * @param array $data
     * @return void
     * @throws Exception
     */
    protected function _page_filter(array &$data)
    {
        foreach ($data as &$vo) {
            $vo['area'] = [$vo['province'],$vo['city'],$vo['county']];
            $vo['startAt'] = date('Y-m-d',$vo['startAt']);
            $vo['endAt'] = date('Y-m-d',$vo['endAt']);
        }
    }

    /**
     * 获取多条租户信息
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function list()
    {
        $query = SysTenant::mQuery();
        $query->where(['is_deleted' => 0]);

        // 数据列表搜索过滤
        $query->equal('tenant_id,tenant_code,status')->dateBetween('created_at');
        $query->like('tenant_name,auth_status');
        $query->dataScope('created_by');
        $lists = $query->order('id ASC')->page(false,false);
        sysoplog('租户管理', '租户列表获取成功');
        $this->success('数据获取成功', $lists['list']);
    }

    /**
     * 获取一条租户详情
     * @login true
     * @return void
     */
    public function detail()
    {
        $tenant = SysTenant::detail($this->request->param('tenantId'));
        $tenant['area'] = [$tenant['province'],$tenant['city'],$tenant['county']];
        sysoplog('租户管理', '租户获取成功');
        $this->success('操作成功', $tenant);
    }

    /**
     * 添加租户
     * @auth true
     * @return void
     */
    public function add()
    {
        sysoplog('租户管理', '租户保存成功');
        SysTenant::mForm('form');
    }

    /**
     * 更新租户
     * @login true
     * @return void
     */
    public function edit()
    {
        sysoplog('租户管理', '租户更新成功');
        SysTenant::mForm('form');
    }

    /**
     * 添加表单处理
     * @param array $data
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    protected function _add_form_filter(array &$data)
    {
        // 检查 'id' 键是否存在，并且它的值不是 null
        if (!isset($data['id']) || !$data['id']) {
            $data['tenantId'] = CodeExtend::snId();
            $data['tenantCode'] = CodeExtend::uniqidNumber(12,'80');
            $data['startAt'] = time();
            $data['endAt'] = time() + 365*24*60*60;
        }
    }


    /**
     * 添加表单处理
     * @param array $data
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    protected function _edit_form_filter(array &$data)
    {
        if($data['area']){
            $data['province'] = $data['area'][0] ?? null;
            $data['city'] = $data['area'][1] ?? null;
            $data['county'] = $data['area'][2] ?? null;
        }
        if($data['startAt']){
            $data['startAt'] = strtotime($data['startAt']);
        }
        if($data['endAt']){
            $data['endAt'] = strtotime($data['endAt']);
        }
    }

    /**
     * 修改租户状态
     * @auth true
     * @return void
     */
    public function state()
    {
        sysoplog('租户管理', '租户状态更改成功');
        SysTenant::mSave($this->_vali([
            'status.in:0,1' => '状态值范围异常！',
            'status.require' => '状态值不能为空！',
        ]));
    }

    /**
     * 租户延期
     * @auth true
     * @return void
     */
    public function extension()
    {
        $tenant = SysTenant::mk()
            ->where('id', (int)$this->request->post('id'))
            ->where('is_deleted', 0)
            ->findOrEmpty();

        if (!$tenant->isEmpty()) {
            // 假设 end_at 是一个 UNIX 时间戳
            $newEndAt = $tenant->end_at + (365 * 24 * 60 * 60);
            if ($tenant->save(['end_at' => $newEndAt])) {
                $this->success('租户延期成功');
            } else {
                $this->error('租户延期失败');
            }
        } else {
            $this->error('租户未找到或已删除');
        }

    }

    /**
     * 移到回收站
     * @auth true
     * @return void
     */
    public function delete()
    {
        sysoplog('租户管理', '租户删除成功');
        $tenantId = $this->request->post('tenantId');
        //删除密码表
        @unlink(syspath("safefile/table/t_{$tenantId}.db"));
        SysTenant::mSave(['is_deleted' => 1]);
    }

    /**
     * 租户审核
     * @auth true
     * @return void
     */
    public function toExamine()
    {
        sysoplog('租户管理', '租户审核');
        SysTenant::mForm();
    }

    /**
     * 租户选择器
     * @login true
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function tenantSelector()
    {
        $query = SysTenant::mQuery();
        $query->where(['is_deleted' => 0]);

        // 数据列表搜索过滤
        $query->equal('tenant_code,status')->dateBetween('created_at');
        $query->like('tenant_name,auth_status');
        $query->dataScope('created_by');
        $lists = $query->order('id ASC')->page(false,false);
        sysoplog('租户管理', '租户列表获取成功');
        $this->success('数据获取成功', $lists['list']);
    }

    /**
     * 租户分配商户
     * @auth true
     * @return void
     * @throws \think\db\exception\DbException
     */
    public function grantMerchant()
    {
        $tenantId = $this->request->post('tenantId');
        $merchantIdList = $this->request->post('merchantIdList');
        $extJson = $this->request->post('extJson', '');

        if (empty($tenantId)) {
            $this->error('租户标识不存在，商户分配失败。');
        }

        try {
            $this->app->db->transaction(function () use ($tenantId, $merchantIdList, $extJson) {
                SysRelation::mk()->where(['object_id' => $tenantId, 'category' => 'SYS_TENANT_HAS_MERCHANT'])->delete();

                if (!empty($merchantIdList)) {
                    $data = [];
                    foreach ($merchantIdList as $k => $v) {
                        $data[] = [
                            'object_id' => $tenantId,
                            'target_id' => $v,
                            'category' => 'SYS_TENANT_HAS_MERCHANT',
                            'ext_json' => json_encode($extJson[$k], JSON_UNESCAPED_UNICODE)
                        ];
                    }

                    $insertResult = SysRelation::mk()->insertAll($data);
                    if (!$insertResult) {
                        // 抛出异常会导致事务自动回滚
                        throw new \Exception('关联商户失败');
                    }
                }
            });

            // 事务提交后，根据是否有商户列表发送不同的成功消息
            if (!empty($merchantIdList)) {
                $this->success('已为该租户分配商户');
            } else {
                $this->success('该租户已移除商户信息');
            }
        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            $this->error($exception->getMessage());
        }
    }

    /**
     * 获取商户列表
     * @auth true
     * @return void
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function merchantSelector()
    {
        $query = SysMerchant::mQuery();
        $query->where(['is_deleted'=>0,'status'=>0]);
        $query->equal('merchant_id');
        $query->like('name,person_name');
        $merchants = $query->order('id ASC')->page(false,false,false);
        $this->success('获取成功！', $merchants['list']);
    }

    /**
     * 获取该租户的所有商户ID
     * @auth true
     * @return void
     */
    public function ownMerchant()
    {
        $merchants = SysRelation::mk()
            ->whereIn('object_id',$this->request->post('tenantId'))
            ->where(['category' => 'SYS_TENANT_HAS_MERCHANT'])
            ->column('target_id');
        $this->success('获取成功！', $merchants);
    }

    /**
     * 租户分配用户
     * @auth true
     * @return void
     * @throws \think\db\exception\DbException
     */
    public function grantUser()
    {
        $tenantId = $this->request->post('tenantId');
        $userIdList = $this->request->post('userIdList');

        // 检查租户ID是否为空
        if (empty($tenantId)) {
            $this->error('租户标识不存在，用户分配失败。');
        }

        try {
            // 使用闭包开始事务
            $this->app->db->transaction(function () use ($tenantId, $userIdList) {
                // 删除该租户下所有用户
                SysRelation::mk()->where(['object_id' => $tenantId, 'category' => 'SYS_TENANT_HAS_USER'])->delete();

                // 如果用户列表不为空，则插入新的用户数据
                if (!empty($userIdList)) {
                    $data = array_map(function ($userId) use ($tenantId) {
                        return [
                            'object_id' => $tenantId,
                            'target_id' => $userId,
                            'category' => 'SYS_TENANT_HAS_USER',
                            'ext_json' => json_encode(['tenantId' => $tenantId, 'userId' => $userId, 'adminType' => 'tenantAdmin'], JSON_UNESCAPED_UNICODE)
                        ];
                    }, $userIdList);

                    // 插入用户数据
                    SysRelation::mk()->insertAll($data);
                }
            });

            // 根据是否有用户列表发送不同的成功消息
            if (!empty($userIdList)) {
                $this->success('已为该租户分配用户');
            } else {
                $this->success('该租户已移除所有用户信息');
            }
        } catch (HttpResponseException $exception) {
            throw $exception;
        } catch (\Exception $exception) {
            $this->error('操作失败：' . $exception->getMessage());
        }
    }

    /**
     * 获取该租户的所有用户ID
     * @auth true
     * @return void
     */
    public function ownUser()
    {
        $merchants = SysRelation::mk()
            ->whereIn('object_id',$this->request->param('tenantId'))
            ->where(['category' => 'SYS_TENANT_HAS_USER'])
            ->column('target_id');
        $this->success('获取成功！', $merchants);
    }
}